package com.xbongbong.paas.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ResultShowRuleEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.ResultShowRuleModel;
import com.xbongbong.paas.pojo.ResultShowRulePojo;
import com.xbongbong.paas.service.ResultShowRuleService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.BaseVO;
import com.xbongbong.pro.constant.CommonConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.enums.errorcodes.ProErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.form.pojo.dto.FormResultRuleSaveDTO;
import com.xbongbong.pro.form.pojo.dto.FormResultShowRuleDTO;
import com.xbongbong.pro.form.pojo.vo.FormResultShowRuleVO;
import com.xbongbong.pro.log.pojo.DetailLogPojo;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ClueEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.service.toolbox.help.LogHelp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author zhouwq
 * @date 2021/11/23 16:58
 */
@Service("resultShowRuleService")
public class ResultShowRuleServiceImpl implements ResultShowRuleService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ResultShowRuleServiceImpl.class);

    @Resource
    private ResultShowRuleModel resultShowRuleModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private LogHelp logHelp;

    @Resource
    private MongoLogHelp mongoLogHelp;

    /**
     * 结果展示不允许设置的类型
     * @return
     */
    public static List<Integer> getResultShowNotAllow(){
        // 1. 其中分割线、描述文本、子表单、图片、多行文本框、附件类型、回收站或未启用字段字段不允许被设置(只有电话子表单类型允许展示)、富文本
        return Arrays.asList(FieldTypeEnum.SEPARATOR.getType(), FieldTypeEnum.MEMO.getType(), FieldTypeEnum.SUB_FORM.getType(), FieldTypeEnum.IMAGE.getType(), FieldTypeEnum.TEXTAREA.getType(), FieldTypeEnum.UPLOAD.getType(),
                FieldTypeEnum.LINK_DATA_MULTI.getType(), FieldTypeEnum.LINK_BUSINESS_MULTI.getType(), FieldTypeEnum.MANUAL_SIGN.getType(),FieldTypeEnum.SELECT_PRODUCT.getType(),
                FieldTypeEnum.RICH_TEXT.getType());
    }

    /**
     * 联系人把关联数据类型去除
     * @return
     */
    public static List<Integer> getResultShowNotAllowContact(){
        // 1. 其中分割线、描述文本、子表单、关联数据、图片、多行文本框、附件类型、回收站或未启用字段字段不允许被设置(只有电话子表单类型允许展示)
        return Arrays.asList(FieldTypeEnum.SEPARATOR.getType(), FieldTypeEnum.MEMO.getType(), FieldTypeEnum.SUB_FORM.getType(),
                FieldTypeEnum.IMAGE.getType(), FieldTypeEnum.TEXTAREA.getType(), FieldTypeEnum.UPLOAD.getType(), FieldTypeEnum.LINK_DATA_MULTI.getType(),FieldTypeEnum.LINK_BUSINESS_MULTI.getType(),
                FieldTypeEnum.MANUAL_SIGN.getType(),FieldTypeEnum.RICH_TEXT.getType());
    }

    /**
     * 根据formId获得结果展示数据
     * @param formResultShowRuleDTO
     * @return
     */
    @Override
    public FormResultShowRuleVO get(FormResultShowRuleDTO formResultShowRuleDTO) throws XbbException{
        FormResultShowRuleVO formResultShowRuleVO = new FormResultShowRuleVO();
        PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();
        Long formId = formResultShowRuleDTO.getFormId();
        String corpid = formResultShowRuleDTO.getCorpid();
        Integer businessType = formResultShowRuleDTO.getBusinessType();
        paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
        if (Objects.isNull(paasFormExplainEntity)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        try {
            List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
            List<Integer> resultShowNotAllow = getResultShowNotAllow();
            //回收站或未启用字段移除
            explainList.removeIf(item -> Objects.equals(BasicConstant.ZERO, item.getIsOpen()) || Objects.equals(BasicConstant.TWO, item.getIsOpen()));
            switch (XbbRefTypeEnum.getByCode(businessType)){
                case CUSTOMER_MANAGEMENT:
                    //把不需要展示的字段类型移除,客户需要把系统字段的客户联系人移除,客户的是否归档是隐藏字段，但是产品说结果展示选择要让他能被客户看到，所以需要特殊处理
                    //将是否归档之外的隐藏字段去除
                    explainList.removeIf(item -> resultShowNotAllow.contains(item.getFieldType())
                            || Objects.equals(item.getAttr(), CustomerManagementEnum.ADD_CONTACT.getAttr())
                            || (!Objects.equals(CustomerManagementEnum.IS_ARCHIVED.getAttr(), item.getAttr()) && Objects.equals(BasicConstant.ONE, item.getEditHide())));
                    break;
                case CLUE:
                    //去除隐藏字段去除
                    explainList.removeIf(item -> resultShowNotAllow.contains(item.getFieldType()) || Objects.equals(BasicConstant.ONE, item.getEditHide()));
                    break;
                case CONTACT:
                    //把不需要展示的字段类型移除,把关联数据中不是关联客户的字段移除,将隐藏字段去除，负责人是隐藏字段，需要展示出来，现在也需要特殊处理
                    explainList.removeIf(item -> getResultShowNotAllowContact().contains(item.getFieldType())
                            || (Objects.equals(FieldTypeEnum.LINK_DATA.getType(),item.getFieldType()) && !Objects.equals(ContactEnum.CUSTOMER_NAME.getAttr(), item.getAttr()))
                            || (!Objects.equals(FieldTypeEnum.OWNERID.getType(), item.getFieldType()) && Objects.equals(BasicConstant.ONE, item.getEditHide())));
                    break;
                case SALES_OPPORTUNITY:
                    //机会去除非 “是否归档”的隐藏字段
                    explainList.removeIf(item -> resultShowNotAllow.contains(item.getFieldType())
                            || (!Objects.equals(SalesOpportunityEnum.IS_ARCHIVED.getAttr(), item.getAttr()) && Objects.equals(BasicConstant.ONE, item.getEditHide())));
                    break;
                default:
                    break;
            }
            Map<String, FieldAttrEntity> communicateExplainMap = new HashMap<>(explainList.size());
            explainList.forEach((item) -> communicateExplainMap.put(item.getAttr(), item));
            List<String> defaultRestltRule = new ArrayList<>();
            //从数据库查询数据
            ResultShowRuleEntity resultShowRuleEntity = resultShowRuleModel.getByFormId(formId, corpid);
            if (Objects.isNull(resultShowRuleEntity)){
                //获得默认展示的字段的attr
                defaultRestltRule = getDefaultRestltRule(businessType, communicateExplainMap);
            }else {
                defaultRestltRule = JSONArray.parseArray(resultShowRuleEntity.getResultRules(), String.class);
            }
            //返回的可选择字段中添加操作和所属位置
            List<JSONObject> checkRepeatHead = CustomerManagementEnum.getCheckRepeatHead();
            List<ResultShowRulePojo> resultShowRulePojos = JSONArray.parseArray(String.valueOf(checkRepeatHead)).toJavaList(ResultShowRulePojo.class);
            for (ResultShowRulePojo resultShowRulePojo : resultShowRulePojos){
                boolean flag = Objects.equals(resultShowRulePojo.getLabel(), I18nMessageUtil.getMessage(I18nStringConstant.LOCATION)) ||
                        Objects.equals(resultShowRulePojo.getLabel(), I18nMessageUtil.getMessage(CommonConstant.OPERATE));
                //是所属位置或操作字段
                if (flag){
                    FieldAttrEntity fieldAttrEntity = new FieldAttrEntity();
                    fieldAttrEntity.setAttr(resultShowRulePojo.getProp());
                    fieldAttrEntity.setAttrName(resultShowRulePojo.getLabel());
                    fieldAttrEntity.setFieldType(resultShowRulePojo.getFieldType());
                    explainList.add(fieldAttrEntity);
                }
            }
            //对返回字段进行封装处理
            List<ResultShowRulePojo> resultShowRulePojoList = new ArrayList<>();
            explainList.forEach(item -> {
                ResultShowRulePojo resultShowRulePojo = new ResultShowRulePojo();
                String attr = item.getAttr();
                resultShowRulePojo.setAttr(attr);
                resultShowRulePojo.setFieldId(item.getFieldId());
                resultShowRulePojo.setFieldType(item.getFieldType());
                resultShowRulePojo.setAttrName(item.getAttrName());
                resultShowRulePojoList.add(resultShowRulePojo);
            });
            formResultShowRuleVO.setFormExplainList(resultShowRulePojoList);
            formResultShowRuleVO.setRuleList(defaultRestltRule);

        }catch(Exception e){
            LOGGER.error("ResultShowRuleServiceImpl.get出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return formResultShowRuleVO;
    }

    /**
     * 对结果展示的默认字段做处理   返回要展示字段的attr
     * @param businessType
     * @return
     */
    public List<String>  getDefaultRestltRule(Integer businessType, Map<String, FieldAttrEntity> communicateExplainMap){
        List<JSONObject> checkRepeatHead = new ArrayList<>();
        //代表第一次点击，给与默认展示字段
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        switch(xbbRefTypeEnum){
            case CUSTOMER_MANAGEMENT:
                checkRepeatHead = CustomerManagementEnum.getCheckRepeatHead();
                break;
            case CONTACT:
                checkRepeatHead = ContactEnum.getCheckRepeatHead();
                break;
            case CLUE:
                checkRepeatHead = ClueEnum.getCheckRepeatHead();
                break;
            case SALES_OPPORTUNITY:
                checkRepeatHead = SalesOpportunityEnum.getCheckRepeatHead();
                break;
            default:
                break;
        }
        //判断默认字段中在当前表单解释中是否有处于未启用或回收站的数据
        List<String> newResultShowRulePojos = new ArrayList<>();
        List<ResultShowRulePojo> resultShowRulePojos = JSONArray.parseArray(String.valueOf(checkRepeatHead)).toJavaList(ResultShowRulePojo.class);
        for (ResultShowRulePojo resultShowRulePojo: resultShowRulePojos){
            boolean ruleFlag = Objects.equals(resultShowRulePojo.getLabel(), I18nMessageUtil.getMessage(I18nStringConstant.LOCATION)) ||
                    Objects.equals(resultShowRulePojo.getLabel(), I18nMessageUtil.getMessage(CommonConstant.OPERATE));
            if (StringUtil.isNotEmpty(resultShowRulePojo.getAttr())){
                FieldAttrEntity fieldAttrEntity = communicateExplainMap.get(resultShowRulePojo.getAttr());
                if (Objects.nonNull(fieldAttrEntity)){
                    //判断是否处于未启用或回收站
                    Integer isOpen = fieldAttrEntity.getIsOpen();
                    //isOpen为0代表不启用，为1代表启用  为2代表是在回收站中
                    boolean flag = Objects.nonNull(isOpen) && (Objects.equals(BasicConstant.ZERO, isOpen) || Objects.equals(BasicConstant.TWO, isOpen));
                    if (!flag){
                        newResultShowRulePojos.add(resultShowRulePojo.getAttr());
                    }
                }
            }else if (Objects.isNull(resultShowRulePojo.getAttr()) && ruleFlag){
                newResultShowRulePojos.add(resultShowRulePojo.getProp());
            }
        }
        return newResultShowRulePojos;
    }


    public static void main(String[] args) {
        List<JSONObject> checkRepeatHead = CustomerManagementEnum.getCheckRepeatHead();
        System.out.println(checkRepeatHead + "33333");
        String s = checkRepeatHead.toString();
        System.out.println(s + " 222222");
        List<ResultShowRulePojo> list = JSONArray.parseArray(String.valueOf(checkRepeatHead)).toJavaList(ResultShowRulePojo.class);
        for (ResultShowRulePojo resultShowRulePojo: list){
            System.out.println(resultShowRulePojo);
        }
    }

    /**
     * 添加数据
     * @param formResultRuleSaveDTO
     * @return
     */
    @Override
    public BaseVO save(FormResultRuleSaveDTO formResultRuleSaveDTO) throws XbbException{
        BaseVO baseVO = new BaseVO();
        String userName = formResultRuleSaveDTO.getLoginUserName();
        Long formId = formResultRuleSaveDTO.getFormId();
        String corpid = formResultRuleSaveDTO.getCorpid();
        ResultShowRuleEntity resultShowRuleEntity = new ResultShowRuleEntity();
        List<String> ruleList = formResultRuleSaveDTO.getRuleList();
        if (CollectionsUtil.isEmpty(ruleList)){
            throw new XbbException(ProErrorCodeEnum.API_ERROR_260058);
        }
        //设置的规则不允许超过10个
        int size = ruleList.size();
        if (size > BasicConstant.TEN){
            throw new XbbException(ProErrorCodeEnum.API_ERROR_260054);
        }
        try{
           //去数据库查询数据
           ResultShowRuleEntity dbResultShowRuleEntity = resultShowRuleModel.getByFormId(formId, corpid);
           if (Objects.isNull(dbResultShowRuleEntity)){
               //执行插入操作
               resultShowRuleEntity.setCorpid(corpid);
               resultShowRuleEntity.setFormId(formId);
               resultShowRuleEntity.setDel(DelEnum.NORMAL.getDel());
               resultShowRuleEntity.setResultRules(JSONArray.toJSONString(ruleList));
               resultShowRuleModel.insert(resultShowRuleEntity);
           }else{
               //执行更新操作
               String oldObj = dbResultShowRuleEntity.getResultRules();
               Long oldUpdateTime = dbResultShowRuleEntity.getUpdateTime();
               dbResultShowRuleEntity.setResultRules(JSONArray.toJSONString(ruleList));
               resultShowRuleModel.update(dbResultShowRuleEntity);
               //编辑操作添加日志
               // 记录日志
               String newObj = JSONObject.toJSONString(ruleList);
               //根据formId查找表单信息
               PaasFormEntityExt paasFormEntityExt = paasFormModel.getByKey(formId, corpid);
               List<DetailLogPojo> detailArr = logHelp.log4ResultShow(corpid, oldObj, newObj, formId, oldUpdateTime);
               if (Objects.nonNull(paasFormEntityExt)){
                   String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_DUPLICATE_RESULT_UPDATE_FORM), userName, paasFormEntityExt.getName());
                   mongoLogHelp.buildLog4DetailArr(detailArr, corpid, formResultRuleSaveDTO.getUserId(), userName, OperateModuleTypeEnum.PAAS_FORM, OperateTypeEnum.EDIT, formId.toString(),
                           paasFormEntityExt.getName(), memo, formResultRuleSaveDTO.getHttpHeader());

               }



//               List<DetailLogPojo> detailArr = logHelp.getDetailArr4Normal(corpid, OperateModuleTypeEnum.DUPLICATE_RESULT_SHOW, oldObj, newObj);
//               if (CollectionsUtil.isNotEmpty(detailArr)) {
//                   String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_FORM_EXPLAIN), baseDTO.getLoginUserName(), paasFormEntityExt.getName());
//                   String opObjectName = paasFormEntityExt.getName() + I18nMessageUtil.getMessage(I18nStringConstant.FIELD_EXPLAIN);
//                   mongoLogHelp.buildLog4DetailArr(detailArr, corpid, baseDTO.getUserId(), baseDTO.getLoginUserName(), OperateModuleTypeEnum.PAAS_FORM_EXPLAIN, OperateTypeEnum.EDIT, formId.toString(), opObjectName, memo, baseDTO.getHttpHeader());
//               }
           }

       }catch(Exception e){
           LOGGER.error("ResultShowRuleServiceImpl.save 出错：", e);
           throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
       }
        return baseVO;
    }

    @Override
    public Integer update(FormResultRuleSaveDTO formResultRuleSaveDTO) throws XbbException{
        return null;
    }



    /**
     * 根据formId删除数据
     * @param formId 表单id
     * @param corpid 公司id
     * @return
     */
    @Override
    public Integer delete(Long formId, String corpid) throws XbbException {
        return null;
    }

}
